<?php

class Url
{
	/**
	 * The full URL.
	 * 
	 * i.e. http://www.example.com/mysite/mypage.php?test=bla
	 */
	const URL_FULL = 0;
	
	/**
	 * The local part of a URL.
	 * 
	 * i.e. /mysite/mypage.php
	 */
	const URL_LOCAL = 1;
	
	/**
	 * The framework-based URL.
	 * 
	 * i.e. mypage.php
	 */
	const URL_FRAMEWORK = 2;
	
	/**
	 * The server.
	 * 
	 * i.e. www.example.com
	 */
	const URL_SERVER = 3;
	
	/**
	 * The protocol.
	 *
	 * i.e. http
	 */
	const URL_PROTOCOL = 4;
	
	/**
	 * The local part including the GET query.
	 *
	 * i.e. /mysite/mypage.php?test=bla
	 */
	const URL_LOCAL_VARS = 11;
	
	/**
	 * The framework url including the GET query.
	 *
	 * i.e. /mypage.php?test=bla
	 */
	const URL_FRAMEWORK_VARS = 12;
	
	static public function current($type = self::URL_FRAMEWORK)
	{
		// Get the protocol first
		$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) ? 'https' : 'http';
		if ($type == self::URL_PROTOCOL) return $protocol;
		
		// Now get the port, if non-standard
		if ($_SERVER['SERVER_PORT'] != (($protocol == 'http') ? 80 : 443)) {
			$port = ':'.$_SERVER['SERVER_PORT'];
		} else {
			$port = '';
		}
		
		$full = $protocol.'://'.$_SERVER['HTTP_HOST'].$port.$_SERVER['REQUEST_URI'];
		
		return self::convert($full, $type);
	}
	
	/**
	 * Make a local URL absolute.
	 * 
	 * Takes a url of type URL_FRAMEWORK or URL_FRAMEWORK_VARS and turns it into
	 * a url of type URL_LOCAL or URL_LOCAL_VARS respectively.
	 * 
	 * This function is used extensively throughout the framework to make
	 * framework paths independent of the context. So no matter in what directory
	 * the site is installed the path is still correct.
	 *
	 * @param string $url
	 * @return string
	 */
	static public function local($url)
	{
		// IMPORTANT: If you change this function, please make sure that your
		//            changes are also reflected in it's client-side counterpart.
		
		$base = Config::get('uri', '/');
		return $base.$url;
	}
	
	/**
	 * Convert a full URL into any of the types.
	 * 
	 * Most used by this class itself.
	 */
	static public function convert($full, $type)
	{
		// Determine position of question mark, if any
		$query_pos = strpos($full, '?');
		if ($query_pos === false) $query_pos = strlen($full);
		
		switch ($type) {
			case self::URL_FULL:
				return $full;

			case self::URL_FRAMEWORK:
				$full = substr($full, 0, $query_pos);
				$full = substr($full, strpos($full, '://')+3);
				$full = substr($full, strpos($full, '/')+1);
				return substr($full, strlen(Config::get('uri'))-1);
				
			case self::URL_FRAMEWORK_VARS:
				$full = substr($full, strpos($full, '://')+3);
				$full = substr($full, strpos($full, '/'));
				return substr($full, strlen(Config::get('uri'))-1);
				
			case self::URL_LOCAL:
				$full = substr($full, 0, $query_pos);
				$full = substr($full, strpos($full, '://')+3);
				return substr($full, strpos($full, '/'));
				
			case self::URL_LOCAL_VARS:
				$full = substr($full, strpos($full, '://')+3);
				return substr($full, strpos($full, '/'));
			
			case self::URL_SERVER:
				$full = substr($full, 0, $query_pos);
				$full = substr($full, strpos($full, '://')+3);
				return substr($full, 0, strpos($full, '/'));
				
			case self::URL_PROTOCOL:
				return substr($full, 0, strpos($full, '://'));
		}
	}
	
	static public function getVar($varname, $default = null, $gpc = 'gpc')
	{
		if ($gpc == 'gpc' && isset($_REQUEST[$varname])) {
			return $_REQUEST[$varname];
		} elseif (strpos($gpc, 'p') !== false && isset($_POST[$varname])) {
			return $_POST[$varname];
		} elseif (strpos($gpc, 'g') !== false && isset($_GET[$varname])) {
			return $_GET[$varname];
		} elseif (strpos($gpc, 'c') !== false && isset($_COOKIE[$varname])) {
			return $_COOKIE[$varname];
		} else {
			return $default;
		}
	}
	
	static public function fixMagicQuotes()
	{
		if (get_magic_quotes_gpc()) {
			// Yes, we are processing everything twice by running both $_REQUEST
			// *and* $_GET, $_POST, $_COOKIE, but it's still better than leaving
			// some slashed vars lying around, waiting to cause trouble.
			// Remember this function is not meant for production use anyway.
			$in = array(&$_REQUEST, &$_GET, &$_POST, &$_COOKIE);
			while (list($k,$v) = each($in)) {
				foreach ($v as $key => $val) {
					if (!is_array($val)) {
						$in[$k][$key] = stripslashes($val);
						continue;
					}
					$in[] =& $in[$k][$key];
				}
			}
			unset($in);
			
			Event::log('framework.url', 'Had to strip GPC vars. For performance it is strongly recommend to set magic_quotes_gpc = Off in your php.ini', Event::LOG_WARN);
		}
	}
}